const { defineConfig } = require('@vue/cli-service')
const env = process.env.NODE_ENV
const TerserJSPlugin = require('terser-webpack-plugin')
// 是否为生产环境
const isProduction = process.env.NODE_ENV !== 'development'
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// 本地环境是否需要使用cdn
const devNeedCdn = false

// cdn链接
const cdn = {
  // cdn：模块名称和模块作用域命名（对应window里面挂载的变量名称）
  externals: {
    vue: 'Vue',
    vuex: 'Vuex',
    'vue-router': 'VueRouter',
    axios: 'axios',
    dayjs: 'dayjs',
    // 属性名称 element-ui, 表示遇到 import xxx from 'element-ui' 这类引入 'element-ui'的， 不去 node_modules 中找，而是去找 全局变量 ELEMENT
    'element-ui': 'ELEMENT'
  },
  // cdn的css链接
  css: [
    'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css',
    'https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.6/theme-chalk/index.min.css'
  ],
  // cdn的js链接
  js: [
    'https://cdn.bootcss.com/vue/2.6.14/vue.min.js',
    'https://cdn.bootcss.com/vuex/3.6.2/vuex.min.js',
    'https://cdn.bootcss.com/vue-router/3.5.1/vue-router.min.js',

    'https://cdn.bootcss.com/axios/0.26.1/axios.min.js',
    'https://unpkg.com/dayjs'
  ]
}

module.exports = defineConfig({
  publicPath: './',
  lintOnSave: env !== 'production',

  // 关闭生产环境下的SourceMap映射文件
  productionSourceMap: env !== 'production',
  transpileDependencies: true,
  css: {
    sourceMap: env !== 'production' // css sourceMap 配置
  },
  devServer: {
    // host: '127.0.0.1',
    // port: 8801, // 自定义修改8080端口
    proxy: {
      '/api': {
        target: 'https://www.jianshu.com/asimov',
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  },
  chainWebpack: (config) => {
    // 分析打包大小
    if (process.env.npm_config_report) {
      config
        .plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
        .end()
    }

    // 发布模式
    config.when(isProduction, (config) => {
      // ============注入cdn start============
      config.plugin('html').tap((args) => {
        // 生产环境或本地需要cdn时，才注入cdn
        if (isProduction || devNeedCdn) args[0].cdn = cdn
        return args
      })
      // ============注入cdn start============

      // 代码压缩
      config.plugins.push(
        new UglifyJsPlugin({
          uglifyOptions: {
            // 生产环境自动删除console
            compress: {
              drop_debugger: true,
              drop_console: true,
              pure_funcs: ['console.log']
            }
          },
          sourceMap: false,
          parallel: true
        })
      )

      // 公共代码抽离
      config.optimization = {
        splitChunks: {
          cacheGroups: {
            vendor: {
              chunks: 'all', // 三选一："initial" 初始化，"all"(默认就是all)，"async"（动态加载）
              test: /node_modules/,
              name: 'vendor',
              minChunks: 1, // 引入次数，如果为2 那么一个资源最少被引用两次才可以被拆分出来
              maxInitialRequests: 5,
              minSize: 0, // 拆分之前最大的数值，默认为0，即不做限制
              priority: 100
            },
            common: {
              chunks: 'all',
              test: /[\\/]src[\\/]js[\\/]/,
              name: 'common',
              minChunks: 2,
              maxInitialRequests: 5,
              minSize: 0,
              priority: 60
            },
            styles: {
              name: 'styles',
              test: /\.(sa|sc|c)ss$/,
              chunks: 'all',
              enforce: true
            },
            runtimeChunk: {
              name: 'manifest'
            }
          }
        }
      }

      // ============压缩图片 start============
      config.module
        .rule('images')
        .use('image-webpack-loader')
        .loader('image-webpack-loader')
        .options({ bypassOnDebug: true })
        .end()
      // ============压缩图片 end============
    })

    // 开发模式
    config.when(process.env.NODE_ENV === 'development', (config) => {
      config.entry('app').clear().add('./src/main-dev.js')

      config.plugin('html').tap((args) => {
        args[0].isProd = false
        return args
      })
    })
  },
  configureWebpack: (config) => {
    // 生产环境相关配置
    if (isProduction) {
      // gzip压缩
      const productionGzipExtensions = ['html', 'js', 'css']
      config.plugins.push(
        new CompressionWebpackPlugin({
          filename: '[path].gz[query]',
          algorithm: 'gzip',
          test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
          threshold: 10240, // 只有大小大于该值的资源会被处理 10240
          minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
          deleteOriginalAssets: false // 删除原文件
        })
      )
    }
    // 用cdn方式引入，则构建时要忽略相关资源
    if (isProduction || devNeedCdn) config.externals = cdn.externals
  }
})
